﻿using HARTCalibrationTool.SerialPortManager;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace HARTCalibrationTool.Commands.HART
{
    public class HART0ReadUniqueIdentifier : HARTCMDsBase
    {
        protected HARTCMD0ReadUniqueIdentifierStruct _readUniqueIdentifierStruct;

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct HARTCMD0ReadUniqueIdentifierStruct
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
            public byte[] preamble;
            public byte start;
            public byte address;
            public byte cmd;
            public byte size;
            public byte parity;
        }
        public HART0ReadUniqueIdentifier(SerialPortsBase serialPortManager, string commandName) : base(serialPortManager, commandName)
        {
            _readUniqueIdentifierStruct = new HARTCMD0ReadUniqueIdentifierStruct()
            {
                preamble = new byte[5] { 0xff, 0xff, 0xff, 0xff, 0xff },
                start = 0x02,
                address = 0x80,
                cmd = 0x00,
                size = 0x00,
                parity = 0x82
            };
        }

        public void SetPollingAddrInCommandCode(byte addr)
        {
            if ((addr >= 0) && (addr <= 0x0F))
            {
                _readUniqueIdentifierStruct.address |= addr;
            }
            else
            {
                SerialPortsBase.PrintMessage($"短地址({addr})设置错误");
            }
        }

        protected override async Task SendCMD()
        {
            byte[] tempData = new byte[16];
            byte[] cmdCodeBytes = StructToBytes<HARTCMD0ReadUniqueIdentifierStruct>(_readUniqueIdentifierStruct);

            Array.Copy(cmdCodeBytes, 5, tempData, 0, 4);
            cmdCodeBytes[cmdCodeBytes.Length - 1] = Utils.GetHARTCRC(tempData, 4);

            SerialPortsBase.PrintMessage("--> " + Utils.HexToString(cmdCodeBytes));
            await SerialPortMager.SerialPortWrite(cmdCodeBytes);
        }

        public override async Task ParseResponse(byte[] data)
        {
            List<string> parts = new List<string>();
            byte[] bytes = Utils.GetHARTDataFrame(data);
            string channel = ((byte)CurrentGroupChannel - 1).ToString();

            await Task.Run(() => {
                SerialPortsBase.PrintMessage("<-- " + $"{Utils.HexToString(data)}");

                this.SetShortAddress((byte)(bytes[1] & 0x0f));
                this.SetDeviceID(bytes[15], bytes[16], bytes[17]);

                SetTransducersStatus(true);

                // Polling Address
                parts.Add(channel + "#1#" + (bytes[1] & 0x0f).ToString());
                // Deivce ID
                parts.Add(channel + "#2#" + (((uint)bytes[15] << 16) + (((uint)bytes[16] << 8) + bytes[17])).ToString());
                // HART Revision
                parts.Add(channel + "#3#" + "0x" + bytes[10].ToString("X2"));
                // Software Revision
                parts.Add(channel + "#4#" + "0x" + bytes[12].ToString("X2"));
                // Hardware Revision
                parts.Add(channel + "#5#" + "0x" + ((bytes[13] >> 3) & 0x1F).ToString("X2"));
                // Manufacturer Identification
                //parts.Add(channel + "#6#" + "0x" + (((ushort)bytes[23] << 8) + bytes[24]).ToString("X4"));
                SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 All"], parts);

                // Device ID
                parts.Clear();
                parts.Add((((uint)bytes[15] << 16) + (((uint)bytes[16] << 8) + bytes[17])).ToString());
                if (channel == "0")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl1 LongAddress"], parts);
                }
                else if (channel == "1")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl2 LongAddress"], parts);
                }

                else if (channel == "2")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl3 LongAddress"], parts);
                }
                else if (channel == "3")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl4 LongAddress"], parts);
                }
                else if (channel == "4")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl5 LongAddress"], parts);
                }
                else if (channel == "5")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl6 LongAddress"], parts);
                }
                else if (channel == "6")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl7 LongAddress"], parts);
                }
                else if (channel == "7")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl8 LongAddress"], parts);
                }
                else if (channel == "8")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl9 LongAddress"], parts);
                }
                else if (channel == "9")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl10 LongAddress"], parts);
                }
                else if (channel == "10")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl11 LongAddress"], parts);
                }
                else if (channel == "11")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl12 LongAddress"], parts);
                }
                else if (channel == "12")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl13 LongAddress"], parts);
                }
                else if (channel == "13")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl14 LongAddress"], parts);
                }
                else if (channel == "14")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl15 LongAddress"], parts);
                }
                else if (channel == "15")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl16 LongAddress"], parts);
                }
                else if (channel == "16")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl17 LongAddress"], parts);
                }
                else if (channel == "17")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl18 LongAddress"], parts);
                }
                else if (channel == "18")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl19 LongAddress"], parts);
                }
                else if (channel == "20")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl21 LongAddress"], parts);
                }
                else if (channel == "21")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl22 LongAddress"], parts);
                }
                else if (channel == "22")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl23 LongAddress"], parts);
                }
                else if (channel == "23")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl24 LongAddress"], parts);
                }
                else if (channel == "24")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl25 LongAddress"], parts);
                }
                else if (channel == "25")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl26 LongAddress"], parts);
                }
                else if (channel == "26")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl27 LongAddress"], parts);
                }
                else if (channel == "27")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl28 LongAddress"], parts);
                }
                else if (channel == "28")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl29 LongAddress"], parts);
                }
                else if (channel == "29")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl30 LongAddress"], parts);
                }
                else if (channel == "31")
                {
                    SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #0 chl32 LongAddress"], parts);
                }
            });
        }
        public override void OnFailure()
        {

        }

        public override void OnSuccess()
        {

        }

        public override void OnTimeout()
        {

        }
    }
}
